﻿/*
 * Разработчик: Коледа Андрей
 * Дата: 20.01.2011
 * Время: 17:33
 * Email: koleda.andrey@gmail.com
 */
using System;
using System.Collections.Generic;
using System.Linq;
using FastTravel.DataAccess.Base;
using FastTravel.DataAccess.Interface;
using FastTravel.DB;
using FastTravel.DB.DTO;
using FastTravel.Utilites;
using StructureMap;

namespace FastTravel.BusinessLogic
{
	/// <summary>
	/// Управление курортами
	/// </summary>
	public class ResortManager
	{
		/// <summary>
		/// Хранилище стран
		/// </summary>
		private static IRepository<Country> CountryRepository
		{
			get {return ObjectFactory.GetInstance<IRepository<Country>>();}
		}

		/// <summary>
		/// Хранилище курортов
		/// </summary>
		private static IRepository<Resort> ResortRepository
		{
			get { return ObjectFactory.GetInstance<IRepository<Resort>>(); }
		}

		/// <summary>
		/// Создать курорт
		/// </summary>
		/// <param name="name">Название курорта</param>
		/// <param name="countryId">ID страны</param>
		/// <returns>Курорт</returns>
		public static Resort Add(string name, int countryId)
		{
			if (!string.IsNullOrWhiteSpace(name))
			{
				Country country = CountryRepository.Single(x => x.ID == countryId);
				if (country != null)
				{
					Resort resort = new Resort {AddedDate = DateTime.Now, Name = name};
					country.Resort.Add(resort);
				   // ResortRepository.Add(resort);
				}
			}
			return null;
		}
		
		/// <summary>
		/// Добавить отель в курорт
		/// </summary>
		/// <param name="resortId">ID курорта</param>
		/// <param name="hotel">Отель</param>
		/// <returns>Отель</returns>
		public static Hotel AddHotel(int resortId, Hotel hotel)
		{
			if (hotel != null)
			{
				var resort = ResortRepository.Single(x => x.ID == resortId);
				if (resort != null)
				{			        
					resort.Hotel.Add(hotel);
				}
			}
			return null;
		}
		
		/// <summary>
		/// Получить курорт
		/// </summary>
		/// <param name="id">ID курорта</param>
		/// <returns>Курорт</returns>
		public static Resort Get(int id)
		{
			return ResortRepository.Single(x => x.ID == id);
		}
		
		/// <summary>
		/// Получить все курорты по стране
		/// </summary>
		/// <param name="countryId">ID страны</param>
		/// <returns>Перечень курортов</returns>
		public static IEnumerable<Resort> GetByCountry(int countryId)
		{
			return ResortRepository.GetQuery().Where(x => x.Country.ID == countryId);
		}

		/// <summary>
		/// Получить страницу курортов
		/// </summary>
		/// <param name="start">Начальная страница</param>
		/// <param name="limit">Размер страницы</param>
		/// <param name="sort">Сортировка по полю</param>
		/// <param name="dir">Направление сортировки</param>
		/// <param name="countryId">ID страны</param>
		/// <param name="count">Общее количество</param>
		/// <param name="resortName">Название крорта</param>
		/// <returns>Курорты</returns>
		public static List<Resort> GetPage(int start, int limit, string sort, string dir, string resortName, int countryId, out int count)
		{
			var query = ResortRepository.GetQuery().Select(e => e);

			if (!string.IsNullOrEmpty(resortName))
			{
				query = query.Where(x => x.Name.ToLower().StartsWith(resortName.ToLower()));
			}

			if ((countryId != 0) & (countryId > 0))
			{
				query = query.Where(x => x.Country.ID == countryId);
			}

			count = query.Count();

			if (!string.IsNullOrEmpty(sort))
			{
				query = dir == "ASC"
							? ResortRepository.SortByQuery<Resort>(query, sort, true)
							: ResortRepository.SortByQuery<Resort>(query, sort, false);
			}

			if (start >= 0 && limit > 0)
			{
				query = query.Skip(start).Take(limit);
			}

			return query.ToList();
		}

		/// <summary>
		/// Получить страницу курортов (DTO объекты)
		/// </summary>
		/// <param name="start">Начальная страница</param>
		/// <param name="limit">Размер страницы</param>
		/// <param name="sort">Сортировка по полю</param>
		/// <param name="dir">Направление сортировки</param>
		/// <param name="countryId">ID страны</param>
		/// <param name="count">Общее количество</param>
		/// <param name="resortName">Название крорта</param>
		/// <returns>Курорты</returns>
		public static List<ResortDTO> GetPageDTO (int start, int limit, string sort, string dir, string resortName, int countryId, out int count)
		{
			var query = ResortRepository.GetQuery().Select(e => e);

			if (!string.IsNullOrEmpty(resortName))
			{
				query = query.Where(x => x.Name.ToLower().StartsWith(resortName.ToLower()));
			}

			if (countryId != 0)
			{
				query = query.Where(x => x.Country.ID == countryId);
			}

			count = query.Count();

			if (!string.IsNullOrEmpty(sort))
			{
				query = dir == "ASC"
							? ResortRepository.SortByQuery<Resort>(query, sort, true)
							: ResortRepository.SortByQuery<Resort>(query, sort, false);
			}

			if (start >= 0 && limit > 0)
			{
				query = query.Skip(start).Take(limit);
			}

			List<ResortDTO> result = query.Select(item => new ResortDTO
			                                              	{
			                                              		CountryName = item.Country.Name, 
																CountryID = item.Country.ID, 
																ID = item.ID, 
																Name = item.Name
			                                              	}).ToList();

			return result.ToList();
		}

		/// <summary>
		/// Получить все курорты
		/// </summary>
		/// <returns>Список курортов</returns>
		public static IEnumerable<Resort> GetAll()
		{
			return ResortRepository.GetAll();
		}
		
		/// <summary>
		/// Обновить информацию о курорте
		/// </summary>
		/// <param name="resortId">ID курорта</param>
		/// <param name="name">Название курорта</param>
		/// <param name="countryId">ID страны</param>
		public static void Update(int resortId, string name, int countryId)
		{
			Resort resort = ResortRepository.Single(x => x.ID == resortId);
			if (resort != null)
			{
				Country country = CountryRepository.Single(x => x.ID == countryId);
				if (country != null)
				{
					resort.Country = country;
					resort.Name = name;
					ResortRepository.SaveChanges();
				}
			}
		}

		/// <summary>
		/// Получить общее количество курортов
		/// </summary>
		/// <returns>Количество курортов</returns>
		public static int Count()
		{
			return ResortRepository.GetQuery().Count();
		}

		/// <summary>
		/// Получить общее количество курортов в стране
		/// </summary>
		/// <param name="countryId">ID страны</param>
		/// <returns>Количество курортов</returns>
		public static int Count(int countryId)
		{
			return ResortRepository.GetQuery().Where(x => x.Country.ID == countryId).Count();
		}

		/// <summary>
		/// Удалить курорт
		/// </summary>
		/// <param name="resortId">ID</param>
		public static void Delete(int resortId)
		{
			Resort resort = ResortRepository.Single(x => x.ID == resortId);
			if (resort != null)
			{
				ResortRepository.Delete(resort);
			}
		}

		/// <summary>
		/// Возвращает количество не удаленных отелей
		/// </summary>
		/// <param name="resortId">ID курорта</param>
		/// <returns>TRUE - если есть курорты</returns>
		public static bool HasHotels(int resortId)
		{
			int hotelsCount = ResortRepository.GetQuery().Where(x => (x.Hotel.Any(c => c.Resort.ID == resortId)) && (x.Hotel.Any(u => u.IsArchive == false))).Count();
			if (hotelsCount > 0)
			{
				return true;
			}
			return false;
		}
	}
		
}
